﻿using System;
using Outlook = Microsoft.Office.Interop.Outlook;
using Microsoft.Office.Interop.Outlook;
using System.Runtime.InteropServices;

namespace OutlookMessageWrapper
{
    /// <summary>
    /// Wrapper class for Outlook Document item
    /// </summary>
    class OutlookDocumentItem : OutlookMessageItemWrapper
    {
        public Outlook.DocumentItem Item { get; set; }

        public OutlookDocumentItem(Outlook.DocumentItem olDocument)
        {
            Item = olDocument;

            RegisterEvents();
        }

        /// <summary>
        /// Registers all outlook item events
        /// </summary>
        private void RegisterEvents()
        {
            Item.AfterWrite += new ItemEvents_10_AfterWriteEventHandler(Item_AfterWrite);
            Item.AttachmentAdd += new ItemEvents_10_AttachmentAddEventHandler(Item_AttachmentAdd);
            Item.AttachmentRead += new ItemEvents_10_AttachmentReadEventHandler(Item_AttachmentRead);
            Item.AttachmentRemove += new ItemEvents_10_AttachmentRemoveEventHandler(Item_AttachmentRemove);
            Item.BeforeAttachmentAdd += new ItemEvents_10_BeforeAttachmentAddEventHandler(Item_BeforeAttachmentAdd);
            Item.BeforeAttachmentPreview += new ItemEvents_10_BeforeAttachmentPreviewEventHandler(Item_BeforeAttachmentPreview);
            Item.BeforeAttachmentRead += new ItemEvents_10_BeforeAttachmentReadEventHandler(Item_BeforeAttachmentRead);
            Item.BeforeAttachmentSave += new ItemEvents_10_BeforeAttachmentSaveEventHandler(Item_BeforeAttachmentSave);
            Item.BeforeAttachmentWriteToTempFile += new ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler(Item_BeforeAttachmentWriteToTempFile);
            Item.BeforeAutoSave += new ItemEvents_10_BeforeAutoSaveEventHandler(Item_BeforeAutoSave);
            Item.BeforeCheckNames += new ItemEvents_10_BeforeCheckNamesEventHandler(Item_BeforeCheckNames);
            Item.BeforeDelete += new ItemEvents_10_BeforeDeleteEventHandler(Item_BeforeDelete);
            Item.BeforeRead += new ItemEvents_10_BeforeReadEventHandler(Item_BeforeRead);
            Item.CustomAction += new ItemEvents_10_CustomActionEventHandler(Item_CustomAction);
            Item.CustomPropertyChange += new ItemEvents_10_CustomPropertyChangeEventHandler(Item_CustomPropertyChange);
            Item.Open += new ItemEvents_10_OpenEventHandler(Item_Open);
            Item.PropertyChange += new ItemEvents_10_PropertyChangeEventHandler(Item_PropertyChange);
            Item.Read += new ItemEvents_10_ReadEventHandler(Item_Read);
            Item.Unload += new ItemEvents_10_UnloadEventHandler(Item_Unload);
            Item.Write += new ItemEvents_10_WriteEventHandler(Item_Write);
            Item.Forward += new ItemEvents_10_ForwardEventHandler(Item_Forward);
            Item.Reply += new ItemEvents_10_ReplyEventHandler(Item_Reply);
            Item.ReplyAll += new ItemEvents_10_ReplyAllEventHandler(Item_ReplyAll);
        }

        /// <summary>
        /// Un-registers all outlook item events
        /// </summary>
        private void UnRegisterEvents()
        {
            Item.AfterWrite -= new ItemEvents_10_AfterWriteEventHandler(Item_AfterWrite);
            Item.AttachmentAdd -= new ItemEvents_10_AttachmentAddEventHandler(Item_AttachmentAdd);
            Item.AttachmentRead -= new ItemEvents_10_AttachmentReadEventHandler(Item_AttachmentRead);
            Item.AttachmentRemove -= new ItemEvents_10_AttachmentRemoveEventHandler(Item_AttachmentRemove);
            Item.BeforeAttachmentAdd -= new ItemEvents_10_BeforeAttachmentAddEventHandler(Item_BeforeAttachmentAdd);
            Item.BeforeAttachmentPreview -= new ItemEvents_10_BeforeAttachmentPreviewEventHandler(Item_BeforeAttachmentPreview);
            Item.BeforeAttachmentRead -= new ItemEvents_10_BeforeAttachmentReadEventHandler(Item_BeforeAttachmentRead);
            Item.BeforeAttachmentSave -= new ItemEvents_10_BeforeAttachmentSaveEventHandler(Item_BeforeAttachmentSave);
            Item.BeforeAttachmentWriteToTempFile -= new ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler(Item_BeforeAttachmentWriteToTempFile);
            Item.BeforeAutoSave -= new ItemEvents_10_BeforeAutoSaveEventHandler(Item_BeforeAutoSave);
            Item.BeforeCheckNames -= new ItemEvents_10_BeforeCheckNamesEventHandler(Item_BeforeCheckNames);
            Item.BeforeDelete -= new ItemEvents_10_BeforeDeleteEventHandler(Item_BeforeDelete);
            Item.BeforeRead -= new ItemEvents_10_BeforeReadEventHandler(Item_BeforeRead);
            Item.CustomAction -= new ItemEvents_10_CustomActionEventHandler(Item_CustomAction);
            Item.CustomPropertyChange -= new ItemEvents_10_CustomPropertyChangeEventHandler(Item_CustomPropertyChange);
            Item.Open -= new ItemEvents_10_OpenEventHandler(Item_Open);
            Item.PropertyChange -= new ItemEvents_10_PropertyChangeEventHandler(Item_PropertyChange);
            Item.Read -= new ItemEvents_10_ReadEventHandler(Item_Read);
            Item.Unload -= new ItemEvents_10_UnloadEventHandler(Item_Unload);
            Item.Write -= new ItemEvents_10_WriteEventHandler(Item_Write);
            Item.Forward -= new ItemEvents_10_ForwardEventHandler(Item_Forward);
            Item.Reply -= new ItemEvents_10_ReplyEventHandler(Item_Reply);
            Item.ReplyAll -= new ItemEvents_10_ReplyAllEventHandler(Item_ReplyAll);
        }

        void Item_ReplyAll(object Response, ref bool Cancel)
        {
            if (ReplyAllItem != null)
            {
                ReplyAllItem(Response, ref Cancel);
            }
        }

        void Item_Reply(object Response, ref bool Cancel)
        {
            if (ReplyItem != null)
            {
                ReplyItem(Response, ref Cancel);
            }
        }

        void Item_Forward(object Forward, ref bool Cancel)
        {
            if (ForwardItem != null)
            {
                ForwardItem(Forward, ref Cancel);
            }
        }

        void Item_Write(ref bool Cancel)
        {
            if (Write != null)
            {
                Write(ref Cancel);
            }
        }

        void Item_Unload()
        {
            if (Unload != null)
            {
                Unload();
            }
        }

        void Item_Read()
        {
            if (Read != null)
            {
                Read();
            }
        }

        void Item_PropertyChange(string Name)
        {
            if (PropertyChange != null)
            {
                PropertyChange(Name);
            }
        }

        void Item_Open(ref bool Cancel)
        {
            if (Open != null)
            {
                Open(ref Cancel);
            }
        }

        void Item_CustomPropertyChange(string Name)
        {
            if (CustomPropertyChange != null)
            {
                CustomPropertyChange(Name);
            }
        }

        void Item_CustomAction(object Action, object Response, ref bool Cancel)
        {
            if (CustomAction != null)
            {
                CustomAction(Action, Response, ref Cancel);
            }
        }

        void Item_BeforeRead()
        {
            if (BeforeRead != null)
            {
                BeforeRead();
            }
        }

        void Item_BeforeDelete(object Item, ref bool Cancel)
        {
            if (BeforeDelete != null)
            {
                BeforeDelete(Item, ref Cancel);
            }
        }

        void Item_BeforeCheckNames(ref bool Cancel)
        {
            if (BeforeCheckNames != null)
            {
                BeforeCheckNames(ref Cancel);
            }
        }

        void Item_BeforeAutoSave(ref bool Cancel)
        {
            if (BeforeAutoSave != null)
            {
                BeforeAutoSave(ref Cancel);
            }
        }

        void Item_BeforeAttachmentWriteToTempFile(Attachment Attachment, ref bool Cancel)
        {
            if (BeforeAttachmentWriteToTempFile != null)
            {
                BeforeAttachmentWriteToTempFile(Attachment, ref Cancel);
            }
        }

        void Item_BeforeAttachmentSave(Attachment Attachment, ref bool Cancel)
        {
            if (BeforeAttachmentSave != null)
            {
                BeforeAttachmentSave(Attachment, ref Cancel);
            }
        }

        void Item_BeforeAttachmentRead(Attachment Attachment, ref bool Cancel)
        {
            if (BeforeAttachmentRead != null)
            {
                BeforeAttachmentRead(Attachment, ref Cancel);
            }
        }

        void Item_BeforeAttachmentPreview(Attachment Attachment, ref bool Cancel)
        {
            if (BeforeAttachmentPreview != null)
            {
                BeforeAttachmentPreview(Attachment, ref Cancel);
            }
        }

        void Item_BeforeAttachmentAdd(Attachment Attachment, ref bool Cancel)
        {
            if (BeforeAttachmentAdd != null)
            {
                BeforeAttachmentAdd(Attachment, ref Cancel);
            }
        }

        void Item_AttachmentRemove(Attachment Attachment)
        {
            if (AttachmentRemove != null)
            {
                AttachmentRemove(Attachment);
            }
        }

        void Item_AttachmentRead(Attachment Attachment)
        {
            if (AttachmentRead != null)
            {
                AttachmentRead(Attachment);
            }
        }

        void Item_AttachmentAdd(Attachment Attachment)
        {
            if (AttachmentAdd != null)
            {
                AttachmentAdd(Attachment);
            }
        }

        void Item_AfterWrite()
        {
            if (AfterWrite != null)
            {
                AfterWrite();
            }
        }

        public override string Subject
        {
            get
            {
                return Item.Subject;
            }
            set
            {
                Item.Subject = value;
            }
        }

        public override string EntryID
        {
            get
            {
                return Item.EntryID;
            }
        }

        public override string MessageClass
        {
            get
            {
                return Item.MessageClass;
            }
            set
            {
                Item.MessageClass = value;
            }
        }

        public override string OutlookVersion
        {
            get
            {
                return Item.OutlookVersion;
            }
        }

        public override string Body
        {
            get
            {
                return Item.Body;
            }
            set
            {
                Item.Body = value;
            }
        }

        public override int Size
        {
            get
            {

                return Item.Size;
            }
        }

        public override DateTime CreationTime
        {
            get { return Item.CreationTime; }
        }

        public override DateTime LastModificationTime
        {
            get { return Item.LastModificationTime; }
        }

        public override Application Application
        {
            get { return Item.Application; }
        }

        #region override function & properties
      
        ///<summary>
        ///     Returns an Microsoft.Office.Interop.Outlook.Actions collection that represents
        ///     all the available actions for the item. Read-only.
        ///</summary>
        public override Actions Actions { get { return Item.Actions; } }
        
        ///<summary>
        ///     Returns an Microsoft.Office.Interop.Outlook.Attachments object that represents
        ///     all the attachments for the specified item. Read-only.
        ///</summary>
        public override Attachments Attachments { get { return Item.Attachments; } }
        
        ///<summary>
        ///     Returns a Boolean (bool in C#) that determines if the item is a winner of
        ///     an automatic conflict resolution. Read-only.
        ///</summary>
        public override bool AutoResolvedWinner { get { return Item.AutoResolvedWinner; } }
        
        ///<summary>
        ///     Returns or sets a String (string in C#) representing the billing information
        ///     associated with the Outlook item. Read/write.
        ///</summary>
        public override string BillingInformation { get { return Item.BillingInformation; } set { Item.BillingInformation = value; } }
        
        ///<summary>
        ///     Returns or sets a String (string in C#) representing the categories assigned
        ///     to the Outlook item. Read/write.
        ///</summary>
        public override string Categories { get { return Item.Categories; } set { Item.Categories = value; } }
        
        ///<summary>
        ///     Returns an Microsoft.Office.Interop.Outlook.OlObjectClass constant indicating
        ///     the object's class. Read-only.
        ///</summary>
        public override OlObjectClass Class { get { return Item.Class; } }
        
        ///<summary>
        ///     Returns or sets a String (string in C#) representing the names of the companies
        ///     associated with the Outlook item. Read/write.
        ///</summary>
        public override string Companies { get { return Item.Companies; } set { Item.Companies = value; } }
        
        ///<summary>
        ///     Return the Microsoft.Office.Interop.Outlook.Conflicts object that represents
        ///     the items that are in conflict for any Outlook item object. Read-only.
        ///</summary>
        public override Conflicts Conflicts { get { return Item.Conflicts; } }
        
        ///<summary>
        ///     Returns a String (string in C#) representing the index of the conversation
        ///     thread of the Outlook item. Read-only.
        ///</summary>
        public override string ConversationIndex { get { return Item.ConversationIndex; } }
        
        ///<summary>
        ///     Returns a String (string in C#) representing the topic of the conversation
        ///     thread of the Outlook item. Read-only.
        ///</summary>
        public override string ConversationTopic { get { return Item.ConversationTopic; } }
        
        ///<summary>
        ///     Returns a constant that belongs to the Microsoft.Office.Interop.Outlook.OlDownloadState
        ///     enumeration indicating the download state of the item. Read-only.
        ///</summary>
        public override OlDownloadState DownloadState { get { return Item.DownloadState; } }
        
        ///<summary>
        ///     Returns the Microsoft.Office.Interop.Outlook.FormDescription object that
        ///     represents the form description for the specified Outlook item. Read-only.
        ///</summary>
        public override FormDescription FormDescription { get { return Item.FormDescription; } }
        
        ///<summary>
        ///     Returns an Microsoft.Office.Interop.Outlook.Inspector object that represents
        ///     an inspector initialized to contain the specified item. Read-only.
        ///</summary>
        public override Inspector GetInspector { get { return Item.GetInspector; } }
        
        ///<summary>
        ///     Returns or sets an Microsoft.Office.Interop.Outlook.OlImportance constant
        ///     indicating the relative importance level for the Outlook item. Read/write.
        ///</summary>
        public override OlImportance Importance { get { return Item.Importance; } set { Item.Importance = value; } }
        
        ///<summary>
        ///     Returns a Boolean (bool in C#) that determines if the item is in conflict.
        ///     Read-only.
        ///</summary>
        public override bool IsConflict { get { return Item.IsConflict; } }
        
        ///<summary>
        ///     Returns an Microsoft.Office.Interop.Outlook.ItemProperties collection that
        ///     represents all standard and user-defined properties associated with the Outlook
        ///     item. Read-only.
        ///</summary>
        public override ItemProperties ItemProperties { get { return Item.ItemProperties; } }
        
        ///<summary>
        ///     Returns a Microsoft.Office.Interop.Outlook.Links collection that represents
        ///     the contacts to which the item is linked. Read-only.
        ///</summary>
        public override Links Links { get { return Item.Links; } }
        
        ///<summary>
        ///     This object, member, or enumeration is deprecated and is not intended to
        ///     be used in your code.
        ///</summary>
        public override dynamic MAPIOBJECT { get { return Item.MAPIOBJECT; } }
        
        ///<summary>
        ///     Returns or sets an Microsoft.Office.Interop.Outlook.OlRemoteStatus constant
        ///     that determines the status of an item once it is received by a remote user.
        ///     Read/write.
        ///</summary>
        public override OlRemoteStatus MarkForDownload { get { return Item.MarkForDownload; } set { Item.MarkForDownload = value; } }
        
        ///<summary>
        ///     Returns or sets a String (string in C#) representing the mileage for an item.
        ///     Read/write.
        ///</summary>
        public override string Mileage { get { return Item.Mileage; } set { Item.Mileage = value; } }
        
        ///<summary>
        ///     Returns or sets a Boolean (bool in C#) value that is True to not age the
        ///     Outlook item. Read/write.
        ///</summary>
        public override bool NoAging { get { return Item.NoAging; } set { Item.NoAging = value; } }
        
        ///<summary>
        ///     Returns an Integer (int in C#) value representing the build number of the
        ///     Outlook application for an Outlook item. Read-only.
        ///</summary>
        public override int OutlookInternalVersion { get { return Item.OutlookInternalVersion; } }
        
        ///<summary>
        ///     Returns the parent Object of the specified object. Read-only.
        ///</summary>
        public override dynamic Parent { get { return Item.Parent; } }
        
        ///<summary>
        ///     Returns a Microsoft.Office.Interop.Outlook.PropertyAccessor object that supports
        ///     creating, getting, setting, and deleting properties of the parent Microsoft.Office.Interop.Outlook.DocumentItem
        ///     object. Read-only.
        ///</summary>
        public override PropertyAccessor PropertyAccessor { get { return Item.PropertyAccessor; } }
        
        ///<summary>
        ///     Returns a Boolean (bool in C#) value that is True if the Outlook item has
        ///     not been modified since the last save. Read-only.
        ///</summary>
        public override bool Saved { get { return Item.Saved; } }
        
        ///<summary>
        ///     Returns or sets a constant in the Microsoft.Office.Interop.Outlook.OlSensitivity
        ///     enumeration indicating the sensitivity for the Outlook item. Read/write.
        ///</summary>
        public override OlSensitivity Sensitivity { get { return Item.Sensitivity; } set { Item.Sensitivity = value; } }
        
        ///<summary>
        ///     Returns the Microsoft.Office.Interop.Outlook.NameSpace object for the current
        ///     session. Read-only.
        ///</summary>
        public override NameSpace Session { get { return Item.Session; } }
        
        ///<summary>
        ///     Returns or sets a Boolean (bool in C#) value that is True if the Outlook
        ///     item has not been opened (read). Read/write.
        ///</summary>
        public override bool UnRead { get { return Item.UnRead; } set { Item.UnRead = value; } }
        
        ///<summary>
        ///     Returns the Microsoft.Office.Interop.Outlook.UserProperties collection that
        ///     represents all the user properties for the Outlook item. Read-only.
        ///</summary>
        public override UserProperties UserProperties { get { return Item.UserProperties; } }

        ///<summary>
        ///     Closes and optionally saves changes to the Outlook item.
        /// Parameters:
        ///   SaveMode:
        ///     The close behavior. If the item displayed within the inspector has not been
        ///     changed, this argument has no effect.
        ///</summary>
        public override void Close(OlInspectorClose SaveMode) { ((Outlook._DocumentItem)Item).Close(SaveMode); }
        
        ///<summary>
        ///     Creates another instance of an object.
        ///</summary>
        public override dynamic Copy() { return Item.Copy(); }
        
        ///<summary>
        ///     Deletes an object from the collection.
        ///</summary>
        public override void Delete() { Item.Delete(); }
        
        ///<summary>
        ///     Displays a new Microsoft.Office.Interop.Outlook.Inspector object for the
        ///     item.
        /// Parameters:
        ///   Modal:
        ///     True to make the window modal. The default value is False.
        ///</summary>
        public override void Display(object Modal = null) { Item.Display(Modal); }
        
        ///<summary>
        ///     Moves a Microsoft Outlook item to a new folder.
        /// Parameters:
        ///   DestFldr:
        ///     The destination folder.
        /// Returns:
        ///     An Object that represents the item which has been moved to the designated
        ///     folder.
        ///</summary>
        public override dynamic Move(MAPIFolder DestFldr) { return Item.Move(DestFldr); }
        
        ///<summary>
        ///     Prints the Outlook item using all default settings. The PrintOut method is
        ///     the only Outlook method that can be used for printing.
        ///</summary>
        public override void PrintOut() { Item.PrintOut(); }
        
        ///<summary>
        ///     Saves the Microsoft Outlook item to the current folder or, if this is a new
        ///     item, to the Outlook default folder for the item type.
        ///</summary>
        public override void Save() { Item.Save(); }
        
        ///<summary>
        ///     Saves the Microsoft Outlook item to the specified path and in the format
        ///     of the specified file type. If the file type is not specified, the MSG format
        ///     (.msg) is used.
        /// Parameters:
        ///   Path:
        ///     The path in which to save the item.
        ///   Type:
        ///     The file type to save. Can be one of the following OlSaveAsType constants:
        ///     olHTML, olMSG, olRTF, olTemplate, olDoc,olTXT, olVCal, olVCard, olICal, or
        ///     olMSGUnicode.
        ///</summary>
        public override void SaveAs(string Path, object Type = null) { Item.SaveAs(Path, Type); }
        
        ///<summary>
        ///     Displays the Show Categories dialog box, which allows you to select categories
        ///     that correspond to the subject of the item.
        ///</summary>
        public override void ShowCategoriesDialog() { Item.ShowCategoriesDialog(); }

        #endregion

        /// <summary>
        /// Disposes the Outlook Document item object
        /// </summary>
        /// <param name="disposing"></param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                // Dispose managed resources
            }

            UnRegisterEvents();

            // Dispose unmanaged resources
            base.Dispose(disposing);

            Marshal.ReleaseComObject(Item);
            Item = null;
        }

        #region events
        public override event ItemEvents_10_AfterWriteEventHandler AfterWrite;
        public override event ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
        public override event ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
        public override event ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
        public override event ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
        public override event ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
        public override event ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
        public override event ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
        public override event ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
        public override event ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
        public override event ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
        public override event ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
        public override event ItemEvents_10_BeforeReadEventHandler BeforeRead;
        public override event ItemEvents_10_CustomActionEventHandler CustomAction;
        public override event ItemEvents_10_ForwardEventHandler ForwardItem;
        public override event ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
        public override event ItemEvents_10_OpenEventHandler Open;
        public override event ItemEvents_10_PropertyChangeEventHandler PropertyChange;
        public override event ItemEvents_10_ReadEventHandler Read;
        public override event ItemEvents_10_ReplyAllEventHandler ReplyAllItem;
        public override event ItemEvents_10_ReplyEventHandler ReplyItem;
        public override event ItemEvents_10_UnloadEventHandler Unload;
        public override event ItemEvents_10_WriteEventHandler Write;
        #endregion
    }


}
